package com.aegean.CommercialHotelBookSystem.book.daoImpl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.hibernate.persister.entity.Loadable;

import com.aegean.CommercialHotelBookSystem.book.dao.IBookDao;
import com.aegean.CommercialHotelBookSystem.factory.HibernateSessionFactory;
import com.aegean.CommercialHotelBookSystem.factory.MyTools;
import com.aegean.CommercialHotelBookSystem.model.Book;
import com.aegean.CommercialHotelBookSystem.model.BookDetail;
import com.aegean.CommercialHotelBookSystem.model.Customer;
import com.aegean.CommercialHotelBookSystem.model.Hotel;
import com.aegean.CommercialHotelBookSystem.model.Room;
import com.aegean.CommercialHotelBookSystem.model.component.BookRoomDetail;

public class BookDaoImpl implements IBookDao {
	@Override
	public Session getSession() {
		return HibernateSessionFactory.getSession();
	}

	@Override
	public void closeSession() {
		HibernateSessionFactory.closeSession();
	}

	public List<Book> searchBooks(String book_Time, String hotel_Name,
			String user_Name) {
		Session session = null;
		Transaction tx = null;
		List<Book> books;
		DetachedCriteria dcr = DetachedCriteria.forClass(Book.class);
		if (book_Time != null && book_Time.length() != 0) {
			dcr.add(Restrictions.eq("book_Time", MyTools.toDate(book_Time)));
		}
		if (hotel_Name != null && hotel_Name.length() != 0) {
			dcr.createAlias("book_Hotel", "hotel");
			dcr.add(Restrictions.eq("hotel.hotel_Name", hotel_Name));
		}
		if (user_Name != null && user_Name.length() != 0) {
			dcr.createAlias("book_Customer", "customer");
			dcr.add(Restrictions.eq("customer.person_Login", user_Name));
		}
		try {
			session = getSession();
			tx = session.beginTransaction();
			Criteria cr = dcr.getExecutableCriteria(session);
			cr.add(Restrictions.eq("book_State", 0));
			cr.addOrder(Property.forName("book_Time").desc());
			cr.setCacheable(true);
			books = cr.list();
			for (Book book : books) {
				Hibernate.initialize(book.getBook_Hotel());
				Hibernate.initialize(book.getBook_Customer());
			}
			return books;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public List<BookRoomDetail> searchBookDetails(int book_Id) {
		Session session = null;
		Transaction tx = null;
		List<BookRoomDetail> some;
		List<BookDetail> details = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			some = new ArrayList<BookRoomDetail>();
			Criteria cr = session.createCriteria(BookDetail.class);
			cr.add(Restrictions.eq("bookDetail_Book.book_Id", book_Id));
			cr.setCacheable(true);
			details = cr.list();
			for (BookDetail bookDetail : details) {
				Room room = (Room) session.get(Room.class, bookDetail
						.getBookDetail_Room().getRoom_Id());
				BookRoomDetail one = new BookRoomDetail();
				one.setDetail(bookDetail);
				one.setRoom(room);
				some.add(one);
			}
			return some;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}

	@Override
	public boolean accessBook(String book_Id, List<BookRoomDetail> bookDetails) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Book one = (Book) session.load(Book.class,
					Integer.parseInt(book_Id));
			one.setBook_State(1);
			for (BookRoomDetail bookRoomDetail : bookDetails) {
				Room room = (Room) session.load(Room.class,
						bookRoomDetail.room.getRoom_Id());
				room.setRoom_Count(room.getRoom_Count()
						- bookRoomDetail.getDetail().getBookDetail_Room()
								.getRoom_Count());
			}
			tx.commit();
			return true;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return false;
		} finally {
			closeSession();
		}
	}

	@Override
	public boolean defalseBook(String book_Id) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Book one = (Book) session.load(Book.class,
					Integer.parseInt(book_Id));
			one.setBook_State(2);
			tx.commit();
			return true;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return false;
		} finally {
			closeSession();
		}
	}

	@Override
	public Customer searchCustomer(String book_Id) {
		Session session = null;
		Transaction tx = null;
		Customer one;
		try {
			session = getSession();
			tx = session.beginTransaction();
			Book book=(Book)session.load(Book.class,Integer.parseInt(book_Id));
	        one=(Customer)session.get(Customer.class,book.getBook_Customer().getPerson_Id());
			return one;
		} catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
			return null;
		} finally {
			closeSession();
		}
	}
}
